#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2025/11/1 17:17
# @Author  : summer
# @Email   : 610658552@qq.com
# @File    : view_dingtalk_config.py
# @Software: PyCharm
# @Desc    : DingTalkConfig视图：CRUD+测试发送消息
from rest_framework import filters
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework.generics import GenericAPIView

from sdingding.models import DingTalkConfig
from sdingding.sers.ser_dingtalk_config import DingTalkConfigSerializer
from sdingding.filters.filter_dingtalk_config import DingTalkConfigFilter
from common.utils.pagination import EnhancedPageNumberPagination  # 复用项目分页器
from common.utils.rsp import success_response, error_response

from sdingding.utils.util_dingtalk import DingTalkSender


class DingTalkConfigListCreateView(GenericAPIView):
    """
    DingTalkConfig列表查询 + 新增接口
    - GET: 分页查询钉钉配置列表（支持筛选）
    - POST: 新增钉钉机器人配置
    """
    # 仅查询有效数据（未删除+非压测）
    queryset = DingTalkConfig.objects.filter(is_delete=0, pt_flag=0)
    serializer_class = DingTalkConfigSerializer
    pagination_class = EnhancedPageNumberPagination  # 复用分页器
    filter_backends = [DjangoFilterBackend, filters.OrderingFilter]
    filterset_class = DingTalkConfigFilter  # 关联过滤器
    ordering_fields = ["create_time"]  # 支持按创建时间、名称排序
    ordering = ["-create_time"]  # 默认按创建时间倒序

    def get(self, request):
        """查询钉钉配置列表（带分页和筛选）"""
        # 1. 筛选数据
        filtered_qs = self.filter_queryset(self.get_queryset())
        # 2. 分页处理
        page_qs = self.paginate_queryset(filtered_qs)
        # 3. 序列化返回
        serializer = self.get_serializer(page_qs, many=True)
        paginated_data = self.paginator.get_paginated_response(serializer.data).data
        return success_response(data=paginated_data, message="钉钉配置列表查询成功")

    def post(self, request):
        """新增钉钉机器人配置"""
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)  # 触发序列化器校验
        serializer.save()
        return success_response(
            data=serializer.data,
            message=f"钉钉配置「{serializer.validated_data['name']}」创建成功"
        )


class DingTalkConfigRetrieveUpdateDestroyView(GenericAPIView):
    """
    DingTalkConfig单条操作接口
    - GET: 查询单个配置详情
    - PUT/PATCH: 更新配置（全量/部分）
    - DELETE: 逻辑删除配置
    - POST: 测试发送钉钉消息（扩展接口）
    """
    queryset = DingTalkConfig.objects.all()
    serializer_class = DingTalkConfigSerializer
    lookup_field = "pk"  # 按ID查询

    def get_object(self):
        """获取有效配置（未删除+非压测），不存在则抛异常"""
        instance = super().get_object()
        if instance.is_delete == 1 or instance.pt_flag == 1:
            raise ValueError("钉钉配置不存在或已被删除")
        return instance

    def get(self, request, pk):
        """查询单个钉钉配置详情"""
        instance = self.get_object()
        serializer = self.get_serializer(instance)
        return success_response(data=serializer.data, message="钉钉配置详情查询成功")

    def put(self, request, pk):
        """全量更新钉钉配置（需传所有必填字段）"""
        instance = self.get_object()
        serializer = self.get_serializer(instance, data=request.data, partial=False)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return success_response(data=serializer.data, message=f"钉钉配置「{instance.name}」全量更新成功")

    def patch(self, request, pk):
        """部分更新钉钉配置（仅传需要修改的字段）"""
        instance = self.get_object()
        serializer = self.get_serializer(instance, data=request.data, partial=True)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return success_response(data=serializer.data, message=f"钉钉配置「{instance.name}」部分更新成功")

    def delete(self, request, pk):
        """逻辑删除钉钉配置（仅修改is_delete状态，不物理删除）"""
        instance = self.get_object()
        instance.is_delete = 1
        instance.save()
        return success_response(message=f"钉钉配置「{instance.name}」已删除", data=None)

    def post(self, request, pk):
        """
        扩展接口：使用当前配置发送测试钉钉消息
        请求参数：{"msg_type": "text", "content": "测试消息内容"}
        （支持text/markdown/link等类型，根据实际工具类调整参数）
        """
        try:
            # 1. 获取配置实例和请求参数
            instance = self.get_object()
            msg_type = request.data.get("msg_type", "text")  # 消息类型（默认文本）
            content = request.data.get("content")  # 消息内容

            # 2. 参数校验
            if not content:
                return error_response(message="测试消息内容不能为空", code=400)
            if msg_type not in ["text", "markdown"]:  # 限制支持的消息类型
                return error_response(message=f"不支持的消息类型「{msg_type}」，仅支持text/markdown", code=400)

            # 3. 调用钉钉机器人工具类发送消息
            dingtalk_client = DingTalkSender(
                access_token=instance.access_token,
                secret=instance.secret  # 若有秘钥则传入（加签用）
            )
            # 根据消息类型调用不同发送方法（需工具类支持）
            if msg_type == "text":
                result = dingtalk_client.send_text(content=content)
            elif msg_type == "markdown":
                title = request.data.get("title", "测试消息")  # markdown消息需标题
                result = dingtalk_client.send_markdown(title=title, content=content)

            # 4. 处理发送结果
            if result["success"]:
                return success_response(data={"request_id": result.get("request_id")}, message="测试消息发送成功")
            else:
                return error_response(data={"error_msg": result.get("error_msg")}, message="测试消息发送失败", code=500)

        except Exception as e:
            return error_response(message=f"发送失败：{str(e)}", code=500)
